package com.baichuan.zntx.common;

import com.baichuan.zntx.domain.Location;
import com.baichuan.zntx.domain.vo.CalibrateVo;

import java.util.List;

/**
 * @author mazhanliang
 */
public class GPSUtils {
    // 地球半径（米）
    private static final double EARTH_RADIUS = 6371e3;

    public static boolean isInFence(Location center, int radius, Location location) {
        double centerLat = center.getLatitude(); // 中心经度
        double centerLon = center.getLongitude(); // 中心纬度
        radius /= 100; // 半径（米）

        double pointLat = location.getLatitude(); // 测试点经度
        double pointLon = location.getLongitude(); // 测试点纬度

        return isPointInCircle(centerLat, centerLon, radius, pointLat, pointLon);
    }

    private static boolean isPointInCircle(double centerLat, double centerLon, double radius, double pointLat, double pointLon) {
        double distance = haversineDistance(centerLat, centerLon, pointLat, pointLon);
        return distance <= radius;
    }

    // 计算两点间的Haversine距离
    private static double haversineDistance(double lat1, double lon1, double lat2, double lon2) {
        double dLat = Math.toRadians(lat2 - lat1);
        double dLon = Math.toRadians(lon2 - lon1);

        lat1 = Math.toRadians(lat1);
        lat2 = Math.toRadians(lat2);

        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
            + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);

        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

        return EARTH_RADIUS * c;
    }

    public static Location GpsToPixel(List<CalibrateVo> calibrateVos, Location location){
        double[][] gpsCoordinates = new double[calibrateVos.size()][2];
        double[] pixelY = new double[calibrateVos.size()];
        double[] pixelX = new double[calibrateVos.size()];
        for (int i = 0; i < calibrateVos.size(); i++) {
            gpsCoordinates[i][0] = calibrateVos.get(i).getLatitude();
            gpsCoordinates[i][1] = calibrateVos.get(i).getLongtitude();
            pixelX[i] = calibrateVos.get(i).getX();
            pixelY[i] = calibrateVos.get(i).getY();
        }
        // 训练 RBF 模型并进行插值
        RBFModel rbfX = new RBFModel(gpsCoordinates, pixelX, 0.0001);
        RBFModel rbfY = new RBFModel(gpsCoordinates, pixelY,0.0001);

        // 输入新的 GPS 坐标
        double[] newGpsPoint = {location.getLatitude(), location.getLongitude()};

        // 预测新的像素坐标
        double predictedX = rbfX.interpolate(newGpsPoint);
        double predictedY = rbfY.interpolate(newGpsPoint);
        return new Location(predictedX, predictedY);
    }
}
